package com.xnew.encrypt;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**   
* @Title: AESEncrypt.java 
* @Description: TODO(AES加密工具类) 
* @version V1.0   
*/
public class AESEncrypt {

	private static Key key = null;
	private static Cipher cipher = null;
	private static AESEncrypt instance = null;
	private static final String path = AESEncrypt.class.getProtectionDomain().getCodeSource().getLocation().getPath();
	
	private static String str = "测试字符串";
	
	static {
		try {
			String keyByFile = AESEncrypt.getInstace().loadKeyByFile(path);
			String decrypt = RSAEncrypt.getInstace().publicKeyDecrypt(keyByFile);
			byte[] decode = Base64.decode(decrypt);
			key = new SecretKeySpec(decode, "AES");
			cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private AESEncrypt(){}
	public static AESEncrypt getInstace(){
		if (instance == null) {
			instance = new AESEncrypt();
		}
		return instance;
	}
	
	public static void main(String[] args) {
		String encrypt = AESEncrypt.getInstace().encrypt(str);
		System.out.println(encrypt);
		String decrypt = AESEncrypt.getInstace().decrypt(encrypt);
		System.out.println(decrypt);
	}
	
	/**
	 * @Title: genKey   
	 * @Description: TODO 密钥生成器
	 * @param:  filePath      
	 * @return: void      
	 * @throws
	 */
	@SuppressWarnings("unused")
	private void genKey(String filePath){
		try {
			KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
			keyGenerator.init(new SecureRandom());
			SecretKey secretKey = keyGenerator.generateKey();
			String aesKeyString = Base64.encode(secretKey.getEncoded());  
			String encrypt = RSAEncrypt.getInstace().privateKeyEncrypt(aesKeyString);
            FileWriter pubfw = new FileWriter(filePath + "/aesKey.keystore");  
            BufferedWriter pubbw = new BufferedWriter(pubfw);  
            pubbw.write(encrypt);
            pubbw.flush();  
            pubbw.close();  
            pubfw.close();  
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * @Title: encrypt   
	 * @Description: TODO 加密操作
	 * @param:  data 原始加密数据(type: String)
	 * @return: String 加密数据明文     
	 * @throws
	 */
	public String encrypt(String data){
		String encryptStr = null;
		try {
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] doFinal = cipher.doFinal(data.getBytes());
			encryptStr = Base64.encode(doFinal);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return encryptStr;
	}
	
	/**
	 * @Title: decrypt   
	 * @Description: TODO 解密操作
	 * @param:  encryptStr 加密数据明文
	 * @return: String 原始数据明文      
	 * @throws
	 */
	public String decrypt(String encryptStr){
		String decryptStr = null;
		try {
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] decode = Base64.decode(encryptStr);
			byte[] doFinal = cipher.doFinal(decode);
			decryptStr = new String(doFinal);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return decryptStr;
	}
	
	/**
	 * @Title: loadKeyByFile   
	 * @Description: TODO 从文件中输入流中加载密钥 
	 * @param:  path 密钥路径
	 * @throws Exception  加载公钥时产生的异常      
	 * @return: String   密钥串  
	 */
    private String loadKeyByFile(String path) throws Exception {  
        try {  
            BufferedReader br = new BufferedReader(new FileReader(path  
                    + "aesKey.keystore"));  
            String readLine = null;  
            StringBuilder sb = new StringBuilder();  
            while ((readLine = br.readLine()) != null) {  
                sb.append(readLine);  
            }  
            br.close();  
            return sb.toString();  
        } catch (IOException e) {  
            throw new Exception("密钥数据流读取错误");  
        } catch (NullPointerException e) {  
            throw new Exception("密钥输入流为空");  
        }  
    }  

}
